home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 98
/
Skunkware 98.iso
/
src
/
mail
/
pine3.96.tar.gz
/
pine3.96.tar
/
pine3.96
/
pine
/
osdep
/
sendmail
< prev
next >
Wrap
Text File
|
1996-05-02
|
6KB
|
249 lines
/*----------------------------------------------------------------------
Routines used to hand off messages to local agents for sending/posting
The two exported routines are:
1) smtp_command() -- used to get local transport agent to invoke
2) post_handoff() -- used to pass messages to local posting agent
----*/
/*
* Protos for "sendmail" internal functions
*/
static char *mta_parse_post PROTO((METAENV *, BODY *, char *, char *));
static long pine_pipe_soutr_nl PROTO((void *, char *));
/* ----------------------------------------------------------------------
Figure out command to start local SMTP agent
Args: errbuf -- buffer for reporting errors (assumed non-NULL)
Returns an alloc'd copy of the local SMTP agent invocation or NULL
----*/
char *
smtp_command(errbuf)
char *errbuf;
{
#if defined(SENDMAIL) && defined(SENDMAILFLAGS)
char tmp[256];
sprintf(tmp, "%s %s", SENDMAIL, SENDMAILFLAGS);
return(cpystr(tmp));
#else
strcpy(errbuf, "No default posting command.");
return(NULL);
#endif
}
/*----------------------------------------------------------------------
Hand off given message to local posting agent
Args: envelope -- The envelope for the BCC and debugging
header -- The text of the message header
errbuf -- buffer for reporting errors (assumed non-NULL)
----*/
int
mta_handoff(header, body, errbuf)
METAENV *header;
BODY *body;
char *errbuf;
{
char cmd_buf[256], *cmd = NULL;
/*
* A bit of complicated policy implemented here.
* There are two posting variables sendmail-path and smtp-server.
* Precedence is in that order.
* They can be set one of 4 ways: fixed, command-line, user, or globally.
* Precedence is in that order.
* Said differently, the order goes something like what's below.
*
* NOTE: the fixed/command-line/user precendence handling is also
* indicated by what's pointed to by ps_global->VAR_*, but since
* that also includes the global defaults, it's not sufficient.
*/
if(ps_global->FIX_SENDMAIL_PATH
&& ps_global->FIX_SENDMAIL_PATH[0]){
cmd = ps_global->FIX_SENDMAIL_PATH;
}
else if(!(ps_global->FIX_SMTP_SERVER
&& ps_global->FIX_SMTP_SERVER[0])){
if(ps_global->COM_SENDMAIL_PATH
&& ps_global->COM_SENDMAIL_PATH[0]){
cmd = ps_global->COM_SENDMAIL_PATH;
}
else if(!(ps_global->COM_SMTP_SERVER
&& ps_global->COM_SMTP_SERVER[0])){
if(ps_global->USR_SENDMAIL_PATH
&& ps_global->USR_SENDMAIL_PATH[0]){
cmd = ps_global->USR_SENDMAIL_PATH;
}
else if(!(ps_global->USR_SMTP_SERVER
&& ps_global->USR_SMTP_SERVER[0])){
if(ps_global->GLO_SENDMAIL_PATH
&& ps_global->GLO_SENDMAIL_PATH[0]){
cmd = ps_global->GLO_SENDMAIL_PATH;
}
#ifdef DF_SENDMAIL_PATH
/*
* This defines the default method of posting. So,
* unless we're told otherwise use it...
*/
else if(!(ps_global->GLO_SMTP_SERVER
&& ps_global->GLO_SMTP_SERVER[0])){
strcpy(cmd = cmd_buf, DF_SENDMAIL_PATH);
}
#endif
}
}
}
*errbuf = '\0';
if(cmd){
dprint(4, (debugfile, "call_mailer via cmd: %s\n", cmd));
(void) mta_parse_post(header, body, cmd, errbuf);
return(1);
}
else
return(0);
}
/*----------------------------------------------------------------------
Hand off given message to local posting agent
Args: envelope -- The envelope for the BCC and debugging
header -- The text of the message header
errbuf -- buffer for reporting errors (assumed non-NULL)
Fork off mailer process and pipe the message into it
Called to post news via Inews when NNTP is unavailable
----*/
char *
post_handoff(header, body, errbuf)
METAENV *header;
BODY *body;
char *errbuf;
{
char *err = NULL;
#ifdef SENDNEWS
char *s;
if(s = strstr(header->env->date," (")) /* fix the date format for news */
*s = '\0';
if(err = mta_parse_post(header, body, SENDNEWS, errbuf))
sprintf(err = errbuf, "News not posted: \"%s\": %s", SENDNEWS, err);
if(s)
*s = ' '; /* restore the date */
#else /* !SENDNEWS */ /* this is the default case */
sprintf(err = errbuf, "Can't post, NNTP-server must be defined!");
#endif /* !SENDNEWS */
return(err);
}
/*----------------------------------------------------------------------
Hand off message to local MTA; it parses recipients from 822 header
Args: header -- struct containing header data
body -- struct containing message body data
cmd -- command to use for handoff (%s says where file should go)
errs -- pointer to buf to hold errors
----*/
static char *
mta_parse_post(header, body, cmd, errs)
METAENV *header;
BODY *body;
char *cmd;
char *errs;
{
char *result = NULL;
int rv;
PIPE_S *pipe;
dprint(1, (debugfile, "=== mta_parse_post(%s) ===\n", cmd));
if(pipe = open_system_pipe(cmd, &result, NULL,
PIPE_STDERR|PIPE_WRITE|PIPE_PROT|PIPE_NOSHELL|PIPE_DESC)){
if(!pine_rfc822_output(header, body, pine_pipe_soutr_nl,
(TCPSTREAM *) pipe))
strcpy(errs, "Error posting.");
if(close_system_pipe(&pipe) && !*errs){
sprintf(errs, "Posting program %s returned error", cmd);
if(result)
display_output_file(result, "POSTING ERRORS", errs);
}
}
else
sprintf(errs, "Error running \"%s\"", cmd);
if(result){
unlink(result);
fs_give((void **)&result);
}
return(*errs ? errs : NULL);
}
/*
* pine_pipe_soutr - Replacement for tcp_soutr that writes one of our
* pipes rather than a tcp stream
*/
static long
pine_pipe_soutr_nl (stream,s)
void *stream;
char *s;
{
long rv = T;
char *p;
size_t n;
while(*s && rv){
if(n = (p = strstr(s, "\015\012")) ? p - s : strlen(s))
while((rv = write(((PIPE_S *)stream)->out.d, s, n)) != n)
if(rv < 0){
if(errno != EINTR){
rv = 0;
break;
}
}
else{
s += rv;
n -= rv;
}
if(p && rv){
s = p + 2; /* write UNIX EOL */
while((rv = write(((PIPE_S *)stream)->out.d,"\n",1)) != 1)
if(rv < 0 && errno != EINTR){
rv = 0;
break;
}
}
else
break;
}
return(rv);
}